using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;
using UnityEngine;

namespace Nirvana
{
    /// <summary>
    /// 项目资源加载主入口：
    /// </summary>
    public class AssetLoadKit:UnitySingleton<AssetLoadKit>
    {
        /// <summary>
        /// 加载一个prefab
        /// 注意：主动加载一个prefab，需要自己不用的时候，去调用Free去释放引用计数，不要造成内存泄漏
        /// </summary>
        /// <param name="prefabPath"></param>
        /// <param name="onComplete"></param>
        /// <exception cref="Exception"></exception>
        public static void LoadPrefab(string prefabPath,Action<GameObject> onComplete)
        {
           var assetid = AssetBundlePathManager.Instance.Get(prefabPath);
            PrefabPool.Instance.Load(assetid, (prefab) => {
                if (prefab == null)
                {
                    throw new Exception("CreateGameObject error dont find :" + prefabPath);
                }
                onComplete?.Invoke(prefab);
                //PrefabPool.Instance.Free(prefab);
            });

        }

        /// <summary>
        /// 加载一个GameObject
        /// </summary>
        /// <param name="prefabPath"></param>
        /// <param name="onComplete"></param>
        /// <param name="parent"></param>
        public static void LoadAsset(string prefabPath,Action<GameObject> onComplete, Transform parent = null)
        {
            var assetid = AssetBundlePathManager.Instance.Get(prefabPath);
            Instance.Load(assetid, onComplete, parent);
        }

        private void Load(AssetID assetid,Action<GameObject> onComplete, Transform parent = null)
        {
            StartCoroutine(WaitLoad(assetid, (go) => { 
                
                if(go == null)
                {
                    onComplete?.Invoke(null);
                    return;
                }
                if(parent != null) go.transform.SetParent(parent);
                go.transform.localPosition = Vector3.zero; 
                go.transform.localRotation = Quaternion.identity;    
                go.transform.localScale = Vector3.one;
                onComplete?.Invoke(go);
            }));
        }

        private IEnumerator WaitLoad(AssetID assetID, Action<GameObject> onComplete)
        {
            var waitLoadObject = GameObjectPool.Instance.SpawnAsset(assetID);

            yield return waitLoadObject;

            if (!string.IsNullOrEmpty(waitLoadObject.Error))
            {
                Debug.LogErrorFormat("Load object from '{0}' failed: {1}", assetID, waitLoadObject.Error);
                onComplete?.Invoke(null);
                yield break;
            }

            var go = waitLoadObject.GetObject() ;
            if (go == null)
            {
                Debug.LogErrorFormat("Load object from '{0}' failed.", assetID);
                onComplete?.Invoke(null);
                yield break;
            }

            onComplete?.Invoke(go);
        }
    }
}